"""
    Contains a functions witch create or update charge records
    for student in group list.
"""

from mnemoply import model
from mnemoply.utils import Wrapper, applyDiscont


class NeedRechargeError(Exception):

    def __init__(self, recharge_list):
        Exception.__init__(self)

        self.recharge_list = recharge_list


def charge(sigs, month, year, can_recharge=False):
    """
        Takes a student-in-group list and create or update charge
        records for this month and year.
        Recharge list raised out with NeedRechargeError exception.
    """

    # TODO optimize
    # TODO need refactoring
    recharge_list = []
    new_list = []
    for sig in sigs:
        crs = model.ChargeRecord.selectBy(
            billingMonth=month, billingYear=year,
            student=sig.student, studentAgreement=sig.studentAgreement
        )
        hours = sig.group.getPlannedHours(month, year)
        tariff = sig.studentAgreement.customerTariff.tariff[month - 1]
        discont = sig.getDiscont(month)

        # Create wrapper for creation or updating charge record
        info = Wrapper(
            student=sig.student,
            studentAgreement=sig.studentAgreement,
            hours=hours,
            new_discont=discont,
            new_tariff=tariff,
            new_hours=hours,
            new_amount=applyDiscont(tariff * hours, discont),
            group=sig.group,
        )

        if not crs.count():
            new_list.append(info)
        else:
            charge_record = crs[0]
            if info.new_amount != charge_record.amount:
                info.old_tariff = charge_record.tariff
                info.old_hours = charge_record.realHours
                info.old_amount = charge_record.amount
                info.old_discont = charge_record.discont
                info.record = charge_record
                recharge_list.append(info)

    if not can_recharge and len(recharge_list) > 0:
        raise NeedRechargeError(recharge_list)

    records = []
    for info in new_list:
        if not info.hours:
            continue
        charge_record = model.ChargeRecord(
            billingMonth=month,
            billingYear=year,
            student=info.student,
            discont=info.new_discont,
            studentAgreement=info.studentAgreement,
            tariff=info.new_tariff,
            plannedHours=info.hours,
            realHours=info.hours,
            payedHours=info.hours,
        )
        records.append(charge_record)

    for info in recharge_list:
        charge_record = info.record
        charge_record.set(
            tariff=info.new_tariff,
            plannedHours=info.hours,
            realHours=info.hours
        )
        charge_record.discont = info.new_discont
        records.append(charge_record)

    return records
